package redis

import (
	"time"
	"context"
)

// 返回 key 所储存的值的类型，如果 key 不存在，则返回“none”
func (h *Handler) Type(key string) (valueType string, err error) {
	valueType, err = h.Client.Type(context.Background(), key).Result()
	go h.Log("Key-Type", key, valueType, err)
	return
}

// 设置 key 在 millisecond 毫秒后过期，key 过期后将不再可用
func (h *Handler) PExpire(key string, millisecond int64) (status bool, err error) {
	status, err = h.Client.PExpire(context.Background(), key, time.Duration(millisecond)).Result()
	go h.Log("Key-PExpire", []interface{}{key, millisecond}, status, err)
	return
}

// 以 UNIX 时间戳设置 key 在指定具体时间过期，key 过期后将不再可用
func (h *Handler) PExpireAt(key string, timestamp int64) (status bool, err error) {
	status, err = h.Client.PExpireAt(context.Background(), key, time.Unix(timestamp, 0)).Result()
	go h.Log("Key-PExpireAt", []interface{}{key, timestamp}, status, err)
	return
}

// 修改 key 的名称，成功返回 OK ，失败时候返回一个错误
func (h *Handler) Rename(key string, newKey string) (status string, err error) {
	status, err = h.Client.Rename(context.Background(), key, newKey).Result()
	go h.Log("Key-Rename", []interface{}{key, newKey}, status, err)
	return
}

// 移除给定 key 的过期时间，使得 key 永不过期
func (h *Handler) Persist(key string) (status bool, err error) {
	status, err = h.Client.Persist(context.Background(), key).Result()
	go h.Log("Key-Persist", key, status, err)
	return
}

// 将当前数据库的 key 移动到给定的数据库 db 当中
func (h *Handler) Move(key string, db int) (status bool, err error) {
	status, err = h.Client.Move(context.Background(), key, db).Result()
	go h.Log("Key-Move", []interface{}{key, db}, status, err)
	return
}

// 从当前数据库中随机返回一个 key
func (h *Handler) RandomKey() (key string, err error) {
	key, err = h.Client.RandomKey(context.Background()).Result()
	go h.Log("Key-RandomKey", "", key, err)
	return
}

// 序列化给定 key，并返回被序列化的值
func (h *Handler) Dump(key string) (value string, err error) {
	value, err = h.Client.Dump(context.Background(), key).Result()
	go h.Log("Key-Dump", key, value, err)
	return
}

// 反序列化给定的序列化值，并将它和给定的 key 关联，以毫秒为单位为 key 设置生存时间，如果 ttl 为 0 ，那么不设置生存时间
func (h *Handler) Restore(key string, ttl int64, value string) (status string, err error) {
	value, err = h.Client.Restore(context.Background(), key, time.Duration(ttl), value).Result()
	go h.Log("Key-Restore", []interface{}{key, ttl, value}, value, err)
	return
}

// 以秒为单位返回 key 的剩余过期时间
func (h *Handler) TTL(key string) (time time.Duration, err error) {
	time, err = h.Client.TTL(context.Background(), key).Result()
	go h.Log("Key-TTL", key, time, err)
	return
}

// 设置 key 在 second 秒后过期，key 过期后将不再可用
func (h *Handler) Expire(key string, second int64) (status bool, err error) {
	status, err = h.Client.Expire(context.Background(), key, time.Duration(second)).Result()
	go h.Log("Key-Expire", []interface{}{key, second}, status, err)
	return
}

// 用于删除已存在的键，不存在的 key 会被忽略
func (h *Handler) Del(keys ...string) (count int64, err error) {
	count, err = h.Client.Del(context.Background(), keys...).Result()
	go h.Log("Key-Del", keys, count, err)
	return
}

// 以毫秒为单位返回 key 的剩余过期时间
func (h *Handler) PTTL(key string) (t time.Duration, err error) {
	t, err = h.Client.PTTL(context.Background(), key).Result()
	go h.Log("Key-PTTL", key, t, err)
	return
}

// 在新的 key 不存在时修改指定 key 的名称
func (h *Handler) RenameNX(key string, newKey string) (status bool, err error) {
	status, err = h.Client.RenameNX(context.Background(), key, newKey).Result()
	go h.Log("Key-RenameNX", []interface{}{key, newKey}, status, err)
	return
}

// 检查给定的多个 key 是否存在，返回存在的数量
func (h *Handler) Exists(keys ...string) (count int64, err error) {
	count, err = h.Client.Exists(context.Background(), keys...).Result()
	go h.Log("Key-Exists", keys, count, err)
	return
}

// 以指定 UNIX 时间戳格式设置 key 的过期时间，key 过期后将不再可用
func (h *Handler) ExpireAt(key string, timestamp int64) (status bool, err error) {
	status, err = h.Client.ExpireAt(context.Background(), key, time.Unix(timestamp, 0)).Result()
	go h.Log("Key-ExpireAt", []interface{}{key, timestamp}, status, err)
	return
}

// 用于查找所有符合给定模式 pattern 的 key
func (h *Handler) Keys(pattern string) (keys []string, err error) {
	keys, err = h.Client.Keys(context.Background(), pattern).Result()
	go h.Log("Key-Keys", pattern, keys, err)
	return
}

// 迭代获取 Redis 键值，找出满足特定前缀 key 的列表
func (h *Handler) Scan(cursor uint64, match string, count int64) (keys []string, nextCursor uint64, err error) {
	keys, nextCursor, err = h.Client.Scan(context.Background(), cursor, match, count).Result()
	go h.Log("Key-Scan", []interface{}{cursor, match, count}, keys, err)
	return
}
